<template>
  <div class="slider-container" ref="container">
    <div class="slider-track" :style="{ width: `${percentage}%` }"></div>
    <div
      class="slider-thumb"
      :style="{ left: `${percentage}%` }"
      @mousedown="startDrag"
      @touchstart="startDrag"
    ></div>
  </div>
</template>

<script>
export default {
  name: 'CustomSlider',
  props: {
    value: {
      type: Number,
      required: true,
      default: 0,
    },
    min: {
      type: Number,
      required: true,
      default: 0,
    },
    max: {
      type: Number,
      required: true,
      default: 100,
    },
  },
  data() {
    return {
      dragging: false,
      startX: 0,
      containerWidth: 0,
      startValue: 0,
      // Document event listeners references
      mousemoveListener: null,
      mouseupListener: null,
      touchmoveListener: null,
      touchendListener: null,
    };
  },
  computed: {
    percentage() {
      const range = this.max - this.min;
      return ((this.value - this.min) / range) * 100;
    },
  },
  methods: {
    startDrag(event) {
      this.dragging = true;
      this.containerWidth = this.$refs.container.offsetWidth;
      this.startX = this.getMousePos(event);
      this.startValue = this.value;

      // Add document event listeners
      this.mousemoveListener = this.drag.bind(this);
      this.mouseupListener = this.stopDrag.bind(this);
      document.addEventListener('mousemove', this.mousemoveListener);
      document.addEventListener('mouseup', this.mouseupListener);

      if (event.type === 'touchstart') {
        // For touch events, we also need to add touchmove and touchend listeners
        this.touchmoveListener = this.drag.bind(this, event.touches[0]);
        this.touchendListener = this.stopDrag.bind(this);
        document.addEventListener('touchmove', this.touchmoveListener, { passive: false });
        document.addEventListener('touchend', this.touchendListener);

        // Prevent scrolling when touching the slider
        event.preventDefault();
      }
    },
    drag(event, touch = null) {
      if (!this.dragging) return;
      let currentX = this.startX;
      if (touch) {
        // For touch events, get the current X position from the touch object
        currentX = touch.clientX - this.$refs.container.getBoundingClientRect().left;
      } else {
        // For mouse events, use the event's clientX property
        currentX = event.clientX - this.$refs.container.getBoundingClientRect().left;
      }
      const deltaX = currentX - this.startX;
      const newValue = this.startValue + (deltaX / this.containerWidth) * (this.max - this.min);
      this.$emit('input', Math.min(Math.max(this.min, newValue), this.max));
    },
    stopDrag() {
      this.dragging = false;

      // Remove document event listeners
      if (this.mousemoveListener) {
        document.removeEventListener('mousemove', this.mousemoveListener);
        this.mousemoveListener = null;
      }
      if (this.mouseupListener) {
        document.removeEventListener('mouseup', this.mouseupListener);
        this.mouseupListener = null;
      }
      if (this.touchmoveListener) {
        document.removeEventListener('touchmove', this.touchmoveListener, { passive: false });
        this.touchmoveListener = null;
      }
      if (this.touchendListener) {
        document.removeEventListener('touchend', this.touchendListener);
        this.touchendListener = null;
      }
    },
    getMousePos(event) {
      return event.clientX;
    },
  },
};
</script>

